package cn.ewan.cloud.tenant.data.router.core.business.plugin.db;

import cn.ewan.cloud.common.support.Log;
import cn.ewan.cloud.tenant.data.router.core.business.context.TenantContext;
import org.apache.commons.lang3.StringUtils;


/**
 * @author lgh
 * @date 2022/12/14 23:45:24
 * 多租户加工处理器
 */
public abstract class TenantKeyBuilder {


    public static final String EMPTY_STR = "";


    /**
     * 多租户的值转换, 如对db名称进行更换
     *
     * @param logicTag 理论上的逻辑值, 如 dy--db, 需更换为${tenantDomain}--db
     * @return 实际加工后的值
     */
    public String convertTenantTag(String logicTag) {

        //获取当前租户标识
        String tenant = findTenant();
        Log.NORMAL.debug("[process tenant actual tag start] tenant={},logicTag={}", tenant, logicTag);

        //若租户标识为空, 或不匹配多租户的替换规则, 返回原值
        if (StringUtils.isBlank(tenant) || !isMathTenantRule(logicTag)) {
            Log.NORMAL.debug("[process tenant actual tag] not match, tenant={},logicTag={}", tenant, logicTag);
            return logicTag;
        }

        //获取实际值,若为空,则返回原值
        String actualTag = getActualTag(logicTag);
        Log.NORMAL.debug("[process tenant actual tag] get actual tag, tag={}", actualTag);
        if (StringUtils.isBlank(actualTag)) {
            return logicTag;
        }

        //构建多租户的实际标签
        String tenantActualTag = buildTenantActualTag(actualTag, tenant);
        Log.NORMAL.debug("[process tenant actual tag end ] tenantActualTag={}", tenantActualTag);
        return tenantActualTag;
    }


    /**
     * 组装最后的
     *
     * @param actualTag
     * @param tenantDomain
     * @return
     */
    protected abstract String buildTenantActualTag(String actualTag, String tenantDomain);


    /**
     * 获取实际需保留的值
     *
     * @param logicTag
     * @return
     */
    protected abstract String getActualTag(String logicTag);

    /**
     * 是否匹配做租户处理的规则
     *
     * @param logicTag
     * @return
     */
    protected abstract boolean isMathTenantRule(String logicTag);


    /**
     * 获取租户表示
     *
     * @return
     */
    private String findTenant() {
        String tenantDomain = TenantContext.getTenant();
        if (StringUtils.isBlank(tenantDomain)) {
            return EMPTY_STR;
        }
        return tenantDomain;
    }

}
